package com.sneakxy.cloudbase.platform.seata;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.cloud.loadbalancer.blocking.client.BlockingLoadBalancerClient;

import com.alibaba.cloud.seata.feign.CloudBaseSeataFeignBlockingLoadBalancerClient;
import com.alibaba.cloud.seata.feign.CloudBaseSeataFeignClient;
import com.alibaba.cloud.seata.feign.SeataFeignClient;

import feign.Client;

public class CloudBaseSeataFeignObjectWrapper {

	private static final Log LOG = LogFactory.getLog(CloudBaseSeataFeignObjectWrapper.class);
	
	private final BeanFactory beanFactory;

	public CloudBaseSeataFeignObjectWrapper(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}

	public Object wrap(Object bean) {
		if (bean instanceof Client && !(bean instanceof SeataFeignClient)) {
			if (bean.getClass().getName().equals(
					"org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient")) {
				return new CloudBaseSeataFeignBlockingLoadBalancerClient(getClient(bean),
						beanFactory.getBean(BlockingLoadBalancerClient.class));
			}
			return new CloudBaseSeataFeignClient(this.beanFactory, (Client) bean);
		}
		return bean;
	}
	
	private Client getClient(Object bean) {
		try {
			return (Client) FieldUtils.readDeclaredField(bean, "delegate", true);
		} catch (Exception e) {
			LOG.error("get delegate client error", e);
		}
		return null;
	}
	
}
